#pragma once
#include <list>

#include "Mutex.h"
#include "AutoLock.h"
using namespace yazi::thread;

namespace yazi{
namespace utility{

template<class T>
class ObjectPool{
public:
    ObjectPool();
    ~ObjectPool();
    void init(int max);
    T* allocate();
    void release(T* p);
    
private:
    std::list<T*> m_pool;
    Mutex m_mutex;
};

template <class T>
ObjectPool<T>::ObjectPool()
{
}

template <class T>
ObjectPool<T>::~ObjectPool()
{
    AutoLock lock(&m_mutex);
    for (auto it = m_pool.begin(); it != m_pool.end(); ++it)
    {
        if ((*it) != nullptr)
        {
            delete (*it);
        }
    }
    m_pool.clear();
}

template <class T>
void ObjectPool<T>::init(int max)
{
    AutoLock lock(&m_mutex);
    for (int i = 0; i < max; ++i)
    {
        m_pool.push_back(new T());
    }
}

template <class T>
T *ObjectPool<T>::allocate()
{
    AutoLock lock(&m_mutex);
    if (m_pool.empty())
        return nullptr;
    T *ret = m_pool.front();
    m_pool.pop_front();
    return ret;
}

template <class T>
void ObjectPool<T>::release(T *p)
{
    if (!p)
        return;
    AutoLock lock(&m_mutex);
    m_pool.push_back(p);
}

}}


